"""
Seaborn 散点图（Scatterplot）基础示例

知识点：
1. 基本散点图绘制
2. 使用 hue 参数添加分类维度
3. 使用 size 参数表示数值大小
4. 使用 style 参数区分不同类别
5. 调整点的透明度和大小
"""

import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib
import pandas as pd
import numpy as np

# 先设置 seaborn 主题
sns.set_theme(style="whitegrid")

# 然后强制设置中文字体（必须在 set_theme 之后）
plt.rcParams['font.sans-serif'] = ['PingFang HK', 'Hiragino Sans GB', 'STHeiti', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'

# 创建示例数据
np.random.seed(42)
n = 200
data = pd.DataFrame({
    '身高(cm)': np.random.normal(170, 10, n),
    '体重(kg)': np.random.normal(65, 12, n),
    '年龄': np.random.randint(20, 60, n),
    '性别': np.random.choice(['男', '女'], n),
    '运动频率': np.random.choice(['低', '中', '高'], n)
})

# 调整体重与身高的相关性
data['体重(kg)'] = data['身高(cm)'] * 0.5 + np.random.normal(0, 5, n)

# 创建多子图
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
# 为整个图形添加总标题
# suptitle: 设置整个图形的总标题（super title）
# fontsize=16: 设置标题字体大小为16磅
# fontweight='bold': 设置标题字体为粗体
fig.suptitle('Seaborn 散点图基础示例', fontsize=16, fontweight='bold')

# 1. 基础散点图
sns.scatterplot(
    data=data,
    x='身高(cm)',
    y='体重(kg)',
    ax=axes[0, 0]
)
axes[0, 0].set_title('1. 基础散点图')
axes[0, 0].set_xlabel('身高 (cm)')
axes[0, 0].set_ylabel('体重 (kg)')

# 2. 使用 hue 添加颜色分类
sns.scatterplot(
    data=data,
    x='身高(cm)',
    y='体重(kg)',
    hue='性别',
    ax=axes[0, 1]
)
axes[0, 1].set_title('2. 使用 hue 按性别分类')
axes[0, 1].set_xlabel('身高 (cm)')
axes[0, 1].set_ylabel('体重 (kg)')

# 3. 使用 size 表示第三个维度
sns.scatterplot(
    data=data,
    x='身高(cm)',
    y='体重(kg)',
    size='年龄',
    sizes=(20, 200),  # 点大小范围
    alpha=0.6,
    ax=axes[0, 2]
)
axes[0, 2].set_title('3. 使用 size 表示年龄')
axes[0, 2].set_xlabel('身高 (cm)')
axes[0, 2].set_ylabel('体重 (kg)')

# 4. 使用 style 区分类别
sns.scatterplot(
    data=data,
    x='身高(cm)',
    y='体重(kg)',
    style='运动频率',
    s=100,  # 统一点大小
    ax=axes[1, 0]
)
axes[1, 0].set_title('4. 使用 style 按运动频率分类')
axes[1, 0].set_xlabel('身高 (cm)')
axes[1, 0].set_ylabel('体重 (kg)')

# 5. 组合 hue 和 style
sns.scatterplot(
    data=data,
    x='身高(cm)',
    y='体重(kg)',
    hue='性别',
    style='运动频率',
    s=100,
    ax=axes[1, 1]
)
axes[1, 1].set_title('5. 组合 hue 和 style')
axes[1, 1].set_xlabel('身高 (cm)')
axes[1, 1].set_ylabel('体重 (kg)')

# 6. 完整示例：hue + size + style + 透明度
sns.scatterplot(
    data=data,
    x='身高(cm)',
    y='体重(kg)',
    hue='性别',
    size='年龄',
    style='运动频率',
    sizes=(50, 250),
    alpha=0.7,
    palette='Set2',
    ax=axes[1, 2]
)
axes[1, 2].set_title('6. 多维度综合展示')
axes[1, 2].set_xlabel('身高 (cm)')
axes[1, 2].set_ylabel('体重 (kg)')

plt.tight_layout()
plt.savefig('/Users/binming/Desktop/CodeBase/python/Python语法/1-常用库/1-数据分析/Seaborn关系图示例/1-scatterplot_基础.png', 
            dpi=300, bbox_inches='tight')
plt.show()

print("=" * 60)
print("散点图核心参数说明：")
print("=" * 60)
print("x, y        : 指定x轴和y轴的数据列")
print("hue         : 用颜色区分不同类别")
print("size        : 用点的大小表示数值变量")
print("style       : 用不同标记形状区分类别")
print("sizes       : 设置点大小的范围 (min, max)")
print("alpha       : 设置透明度 (0-1)")
print("palette     : 设置调色板")
print("s           : 统一设置所有点的大小")
print("=" * 60)
